﻿using System;
using System.Collections.Generic;
using System.Text;

namespace LK.Math
{
    public partial class Bits
    {


		/// <summary>
		/// 在arr和数组自身的指定位上加1（无舍入操作），返回进位
		/// </summary>
		/// <param name="arr">需要进行操作数组</param>
		/// <param name="index">数据起始索引(从0开始)</param>
		/// <param name="len">数据长度（元素数量）</param>
		/// <param name="bitmov">参数bitmov代表指定位往高位偏移比特数。bitmov=0代表下标index元素的最低位。超出数据范围时将不产生作用，比如mov为-1时不会发生舍入操作</param>
		/// <returns>进位</returns>
		public static bool SelfPlusOne(ulong[] arr, int index, int len, int bitmov){
			ulong bm = 1ul << (bitmov & 63);
			if (bitmov < 0 || (bitmov /= 64) >= len) return false;
			if (arr[bitmov+index] > (~bm))
			{
				int pe = index + len;
				arr[index += bitmov] += bm;
				while (++index != pe) if (++arr[index] != 0) break;
				return index == pe;
			}
			arr[bitmov+index] += bm;
			return false;
		}
		public static bool SelfPlusOne(ulong[] arr,int bitmov=0) {
			return SelfPlusOne(arr, 0, arr.Length, bitmov);
		}

		/// <summary>
		/// 在arr数组自身的指定位上加1（越下限时舍入），返回进位
		/// </summary>
		/// <param name="arr">需要进行操作的数组</param>
		/// <param name="index">数据起始索引(从0开始)</param>
		/// <param name="len">数据长度（元素数量）</param>
		/// <param name="bitmov">参数bitmov代表指定位往高位偏移比特数。bitmov=0代表下标index元素的最低位。超出数据上限时将不产生作用，而低于下限1位时会产生舍入</param>
		/// <returns>进位</returns>
		public static bool SelfPlusOneRound(ulong[] arr, int index, int len, int bitmov){
			return SelfPlusOne(arr, index, len, bitmov == -1 ? 0 : bitmov);
		}
		public static bool SelfPlusOneRound(ulong[] arr, int bitmov = 0)
		{
			return SelfPlusOneRound(arr, 0, arr.Length, bitmov);
		}

		/// <summary>
		/// 在arr数组自身的指定位上加上一个64位无符号数字num，返回进位
		/// </summary>
		/// <param name="arr">需要进行操作的数组</param>
		/// <param name="index">数据起始索引(从0开始)</param>
		/// <param name="len">数据长度（元素数量）</param>
		/// <param name="num">加数</param>
		/// <param name="bitmov">参数bitmov代表指定位置往高位偏移比特数。bitmov=0代表下标index元素的最低位。超出范围上下限数据将被忽略</param>
		/// <returns>进位</returns>
		public static bool SelfPlus(ulong[] arr, int index, int len, ulong num, int bitmov){
			if (bitmov <= -64 || (bitmov / 64) >= len) return false;
			int pe = index + len;
			if (bitmov < 0)
			{
				bitmov &= 63;
				num >>= (64 - bitmov);
				if (arr[index] > ~num)
				{
					arr[index] += num;
					while (++index != pe) if (++arr[index] != 0) return false;
					return true;
				}
				arr[index] += num;
				return false;
			}
			index += bitmov / 64;
			if ((bitmov &= 63) == 0)
			{
				if (arr[index] > ~num)
				{
					arr[index] += num;
					while (++index != pe) if (++arr[index] != 0) return false;
					return true;
				}
				arr[index] += num;
				return false;
			}
			ulong lm = num << bitmov;
			num >>= 64 - bitmov;
			if (arr[index] > (~lm)) { num++; arr[index++] += lm; if (index == pe) return true; }
			else arr[index++] += lm;
			if (index == pe) return false;
			if (arr[index] > (~num))
			{
				arr[index] += num;
				while (++index != pe) if (++arr[index] != 0) return false;
				return true;
			}
			arr[index] += num;
			return false;
		}
		public static bool SelfPlus(ulong[] arr, ulong num, int bitmov = 0) { return SelfPlus(arr, 0, arr.Length, num, bitmov); }
		/// <summary>
		/// 在arr数组自身的指定位上加上一个64位无符号数字num，返回进位
		/// </summary>
		/// <param name="arr">需要进行操作的数组</param>
		/// <param name="index">数据起始索引(从0开始)</param>
		/// <param name="len">数据长度（元素数量）</param>
		/// <param name="num">加数</param>
		/// <param name="bitmov">参数bitmov代表指定位置往高位偏移比特数。bitmov=0代表下标index元素的最低位。超出范围上限数据将被忽略，而越下限数据有可能产生舍入操作</param>
		/// <returns>进位</returns>
		public static bool SelfPlusRound(ulong[] arr, int index, int len, ulong num, int bitmov){
			if (bitmov >= 0 && (bitmov / 64) >= len) return false;
			if (bitmov < -64) return false;
			int pe = index + len;
			if (bitmov == -64)
			{
				if ((long)num < 0)
				{
					while (index != pe) if (++arr[index] != 0) return false;
					return true;
				}
				return false;
			}
			if (bitmov < 0)
			{
				bitmov = -bitmov;
				if (len == 0) return ((num >> (bitmov - 1)) & 1) != 0;
				num = (num >> bitmov) + ((num >> (bitmov - 1)) & 1);
				if (arr[index] > ~num)
				{
					arr[index] += num;
					while (++index != pe) if (++arr[index] != 0) return false;
					return true;
				}
				arr[index] += num;
				return false;
			}
			index += bitmov / 64;
			if ((bitmov &= 63) == 0)
			{
				if (arr[index] > ~num)
				{
					arr[index] += num;
					while (++index != pe) if (++arr[index] != 0) return false;
					return true;
				}
				arr[index] += num;
				return false;
			}
			ulong lm = num << bitmov;
			num >>= 64 - bitmov;
			if (arr[index] > (~lm)) { num++; arr[index++] += lm; if (index == pe) return true; }
			else arr[index++] += lm;
			if (index == pe) return false;
			if (arr[index] > (~num))
			{
				arr[index] += num;
				while (++index != pe) if (++arr[index] != 0) return false;
				return true;
			}
			arr[index] += num;
			return false;
		}
		public static bool SelfPlusRound(ulong[] arr, ulong num, int bitmov) {
			return SelfPlusRound(arr, 0, arr.Length, num, bitmov);
		}

		/// <summary>
		/// 在arrSelf数组的指定位上 加上 arrOther所指定的内容，返回进位。超出操作数据范围上下限的加数数据将被忽略，没有舍入操作
		/// </summary>
		/// <param name="arrSelf">需要进行操作的数组</param>
		/// <param name="indexSelf">操作起始索引(从0开始)</param>
		/// <param name="lenSelf">操作长度</param>
		/// <param name="arrOther">加数数组</param>
		/// <param name="indexOther">加数起始索引（从0开始）</param>
		/// <param name="lenOther">加数数据长度</param>
		/// <param name="bitmov">加数数据往高位偏移比特数。当bitmov=0时表示两者数据由index和len指定的部分的最低位对齐</param>
		/// <returns>进位</returns>
		public static bool SelfPlus(ulong[] arrSelf, int indexSelf, int lenSelf, ulong[] arrOther, int indexOther, int lenOther, int bitmov){
			int destStartIndex = (bitmov < 64 ? 0 : (bitmov >> 6));
			bitmov = bitmov < 0 ? -bitmov : -(bitmov & 63);
			bool flag = false;
			while (destStartIndex < lenSelf)
			{
				ulong tmp = GetULong(arrOther, indexOther,lenOther, bitmov);
				if (flag)
				{
					flag = arrSelf[destStartIndex+indexSelf] >= ~tmp;
					arrSelf[destStartIndex+indexSelf] += tmp + 1;
				}
				else
				{
					flag = arrSelf[destStartIndex+indexSelf] > ~tmp;
					arrSelf[destStartIndex+indexSelf] += tmp;
				}
				bitmov += 64;
				if (tmp == 0 && flag == false && bitmov > lenSelf * 64) return false;
				destStartIndex++;
			}
			return flag;
		}
		public static bool SelfPlus(ulong[] arrSelf, ulong[] arrOther, int bitmov=0) {
			int i = 0;
			bool flag = false;
			while (i < arrSelf.Length)
			{
				if (i >= arrOther.Length)
				{
					if (flag)
						if (!(flag = ++arrSelf[i++] == 0)) break;
						else continue;
					break;
				}
				if (flag)
				{
					flag = arrSelf[i] >= (ulong.MaxValue ^ arrOther[i]);
					arrSelf[i] += arrOther[i] + 1;
				}
				else
				{
					flag = arrSelf[i] > (ulong.MaxValue ^ arrOther[i]);
					arrSelf[i] += arrOther[i];
				}
				++i;
			}
			return flag;
		}
		/// <summary>
		///  在arrSelf数组的指定位上加上arrOther数组指定的内容，越上限部分忽略，越下限部分舍入，返回进位
		/// </summary>
		/// <param name="arrSelf">需要进行操作的数组</param>
		/// <param name="indexSelf">操作起始索引(从0开始)</param>
		/// <param name="lenSelf">操作长度</param>
		/// <param name="arrOther">加数数组</param>
		/// <param name="indexOther">加数起始索引（从0开始）</param>
		/// <param name="lenOther">加数数据长度</param>
		/// <param name="bitmov">加数数据往高位偏移比特数。当bitmov=0时表示两者数据由index和len指定的部分的最低位对齐</param>
		/// <returns>进位</returns>
		public static bool SelfPlusRound(ulong[] arrSelf, int indexSelf, int lenSelf, ulong[] arrOther, int indexOther, int lenOther, int bitmov) { 
			int destStartIndex = (int)(bitmov < 64 ? 0 : (bitmov >> 6));
			bool flag = bitmov < 0 ? (long)GetULong(arrSelf,indexSelf, lenSelf, -64 - bitmov) < 0 : false;
			bitmov = bitmov < 0 ? -bitmov : -(bitmov & 63);
			while (destStartIndex<lenSelf)
			{
				ulong tmp = GetULong(arrOther, indexOther, lenOther, bitmov);
				if (flag)
				{
					flag = arrSelf[indexSelf+destStartIndex] >= ~tmp;
					arrSelf[indexSelf+ destStartIndex] += tmp + 1;
				}
				else
				{
					flag = arrSelf[indexSelf+destStartIndex] > ~tmp;
					arrSelf[indexSelf +destStartIndex] += tmp;
				}
				bitmov += 64;
				if (tmp == 0 && flag == false && bitmov > (long) lenSelf * 64)return false;
				destStartIndex++;
			}
			return flag;
		}
		public static bool SelfPlusRound(ulong[] arrSelf, ulong[] arrOther, int bitmov=0)
		{
			return SelfPlusRound(arrSelf, 0, arrSelf.Length, arrOther, 0, arrOther.Length, bitmov);
		}
		/// <summary>
		/// 将arrSource数组指定部分护具按指定位偏移，与按指定位偏移的1叠加，然后将结果保存到arrDest数组中的指定位置去。位偏移量都是相对结果数组arrDest而言，超出范围的数据将被舍去
		/// </summary>
		/// <param name="arrDest">存放结果的数组</param>
		/// <param name="indexDest">结果数组存放起始索引（从0开始）</param>
		/// <param name="lenDest">结果数组存放数据长度</param>
		/// <param name="arrSource">被加数数组</param>
		/// <param name="indexSource">被加数数组起始索引（从0开始）</param>
		/// <param name="lenSource">被加数数据长度</param>
		/// <param name="bitmovSource">被加数相对结果数组指定部分最低位的位偏移</param>
		/// <param name="bitmov">加数1相对结果数组指定部分最低位的位偏移</param>
		/// <returns>进位（超出结果数组数据范围）</returns>
		public static bool PlusOne(ulong[] arrDest, int indexDest,int lenDest, ulong[] arrSource, int indexSource, int lenSource, int bitmovSource, int bitmov){
			bitmovSource = -bitmovSource;
			ulong ull = 1ul << (bitmov & 63);
			if (bitmov > 0) bitmov = bitmov / 64;
			bool flag = false;
			for (int i = 0; i < lenDest; ++i, bitmovSource += 64)
			{
				ulong tmp = GetULong(arrSource, indexSource,lenSource, bitmovSource);
				if (flag)
				{
					flag = (arrDest[indexDest+i] = ++tmp) == 0;
				}
				else if (i == bitmov)
				{
					flag = tmp > ~ull;
					arrDest[indexDest+i] = tmp + ull;
				}
				else arrDest[i] = tmp;
			}
			return flag;
		}
		public static bool PlusOne(ulong[] arrDest, ulong[] arrSource, int bitmovSource=0, int bitmov = 0)
		{
			return PlusOne(arrDest, 0, arrDest.Length, arrSource, 0, arrSource.Length, bitmovSource,bitmov);
		}

		/// <summary>
		/// 将arrSource数组指定部分护具按指定位偏移，与按指定位偏移的1叠加，然后将结果保存到arrDest数组中的指定位置去。位偏移量都是相对结果数组arrDest而言，超出上限的数据将被舍去，超下限的数据视情况舍入。
		/// </summary>
		/// <param name="arrDest">存放结果的数组</param>
		/// <param name="indexDest">结果数组存放起始索引（从0开始）</param>
		/// <param name="lenDest">结果数组存放数据长度</param>
		/// <param name="arrSource">被加数数组</param>
		/// <param name="indexSource">被加数数组起始索引（从0开始）</param>
		/// <param name="lenSource">被加数数据长度</param>
		/// <param name="bitmovSource">被加数相对结果数组指定部分最低位的位偏移</param>
		/// <param name="bitmov">加数1相对结果数组指定部分最低位的位偏移</param>
		/// <returns>进位（超出结果数组数据范围）</returns>
		public static bool PlusOneRound(ulong[] arrDest, int indexDest, int lenDest, ulong[] arrSource, int indexSource, int lenSource, int bitmovSource, int bitmov) {
			bitmovSource = -bitmovSource;
			ulong tmp = GetULong(arrSource, indexSource,lenSource, bitmovSource - 64);
			ulong ull = 1ul << (bitmov & 63);
			bool flag = tmp < 0;
			if (bitmov >= 0)
			{
				bitmov = bitmov / 64;
			}
			else if (bitmov >= -64)
			{
				flag = flag || (tmp + ull) < 0;
				bitmov = 0; ull = 0;
			}
			for (int i = 0; i < lenDest; ++i, bitmovSource += 64)
			{
				tmp = GetULong(arrSource, indexSource,lenSource, bitmovSource);
				if (i == bitmov)
				{
					if (flag)
					{
						flag = tmp >= ~ull;
						arrDest[indexDest+i] = tmp + ull + 1;
					}
					else
					{
						flag = tmp > ~ull;
						arrDest[indexDest+i] = tmp + ull;
					}
				}
				else
				{
					if (flag) flag = (arrDest[indexDest+i] = tmp + 1) == 0;
					else arrDest[indexDest+i] = tmp;
				}
			}
			return flag;
		}
		public static bool PlusOneRound(ulong[] arrDest, ulong[] arrSource, int bitmovSource = 0, int bitmov = 0)
		{
			return PlusOneRound(arrDest, 0, arrDest.Length, arrSource, 0, arrSource.Length, bitmovSource, bitmov);
		}

		/// <summary>
		/// 将arrSource数组指定部分护具按指定位偏移，与按指定位偏移的num叠加，然后将结果保存到arrDest数组中的指定位置去。位偏移量都是相对结果数组arrDest而言，超出范围的数据将被舍去。
		/// </summary>
		/// <param name="arrDest">存放结果的数组</param>
		/// <param name="indexDest">结果数组存放起始索引（从0开始）</param>
		/// <param name="lenDest">结果数组存放数据长度</param>
		/// <param name="arrSource">被加数数组</param>
		/// <param name="indexSource">被加数数组起始索引（从0开始）</param>
		/// <param name="lenSource">被加数数据长度</param>
		/// <param name="bitmovSource">被加数相对结果数组指定部分最低位的位偏移</param>
		/// <param name="num">加数</param>
		/// <param name="bitmov">加数1相对结果数组指定部分最低位的位偏移</param>
		/// <returns>进位（超出结果数组数据范围）</returns>
		public static bool Plus(ulong[] arrDest, int indexDest,int lenDest, ulong[] arrSource, int indexSource,int lenSource, ulong num, int bitmovSource, int bitmov){
			bitmovSource = -bitmovSource;
			ulong ull = num << (bitmov & 63);
			num = (bitmov & 63) == 0 ? 0 : num >> (64 - (bitmov & 63));
			if (bitmov >= 0) bitmov = bitmov / 64;
			else { bitmov = (bitmov - 63) / 64; }
			bool flag = false;
			for (int i = 0; i < lenDest; ++i, bitmovSource += 64)
			{
				ulong tmp = GetULong(arrSource, indexSource,lenSource, bitmovSource);
				ulong t;
				if (i == bitmov) t = ull;
				else if (i == bitmov + 1) t = num;
				else if (!flag) { arrDest[indexDest+i] = tmp; continue; }
				else t = 0;

				if (flag)
				{
					flag = tmp >= ~t;
					arrDest[indexDest+i] = tmp + t + 1;
				}
				else
				{
					flag = tmp > ~t;
					arrDest[indexDest+i] = tmp + t;
				}
			}
			return flag;
		}
		public static bool Plus(ulong[] arrDest, ulong[] arrSource, ulong num, int bitmovSource = 0, int bitmov = 0) {
			return Plus(arrDest, 0, arrDest.Length, arrSource, 0, arrSource.Length,num, bitmovSource, bitmov);
		}

		/// <summary>
		/// 将arrSource数组指定部分护具按指定位偏移，与按指定位偏移的num叠加，然后将结果保存到arrDest数组中的指定位置去。位偏移量都是相对结果数组arrDest而言，超出上限的数据将被舍去，超下限的数据视情况舍入。
		/// </summary>
		/// <param name="arrDest">存放结果的数组</param>
		/// <param name="indexDest">结果数组存放起始索引（从0开始）</param>
		/// <param name="lenDest">结果数组存放数据长度</param>
		/// <param name="arrSource">被加数数组</param>
		/// <param name="indexSource">被加数数组起始索引（从0开始）</param>
		/// <param name="lenSource">被加数数据长度</param>
		/// <param name="bitmovSource">被加数相对结果数组指定部分最低位的位偏移</param>
		/// <param name="num">加数</param>
		/// <param name="bitmov">加数num相对结果数组指定部分最低位的位偏移</param>
		/// <returns>进位（超出结果数组数据范围，舍入导致进位有大于1的可能）</returns>
		public static int PlusRound(ulong[] arrDest, int indexDest,int lenDest, ulong[] arrSource, int indexSource,int lenSource, ulong num, int bitmovSource, int bitmov){
			bitmovSource = -bitmovSource;
			ulong tmp = GetULong(arrSource, indexSource,lenSource, bitmovSource - 64);
			ulong ull = num << (bitmov & 63);
			num = (bitmov & 63) == 0 ? 0 : num >> (64 - (bitmov & 63));
			int flag = 0;
			if (bitmov >= 0)
			{
				bitmov = bitmov / 64;
				flag = (long)tmp < 0?1:0;
			}
			else
			{
				if (bitmov >= -64) flag = ((tmp > ~ull)?1:0) + ((long)(tmp + ull) < 0?1:0);
				else if (bitmov > -128) flag = ((tmp > ~num)?1:0) + ((long)(tmp + num) < 0?1:0);
				else flag = (long)tmp < 0?1:0;
				bitmov = (bitmov - 63) / 64;
			}

			for (int i = 0; i < lenDest; ++i, bitmovSource += 64)
			{
				tmp = GetULong(arrSource,indexSource, lenSource, bitmovSource);
				ulong t = i == bitmov ? ull : i == bitmov + 1 ? num : 0;
				if (flag != 0)
				{
					if (flag == 2)
					{
						flag = tmp == ~0ul || (tmp +1 >= ~t )?1:0;
						arrDest[indexDest+i] = tmp + t + 2;
					}
					else
					{
						flag = tmp >= ~t?1:0;
						arrDest[indexDest+i] = tmp + t + 1;
					}
				}
				else
				{
					flag = tmp > ~t?1:0;
					arrDest[indexDest+i] = tmp + t;
				}
			}
			return flag;
		}
		public static int PlusRound(ulong[] arrDest, ulong[] arrSource, ulong num, int bitmovSource = 0, int bitmov = 0)
		{
			return PlusRound(arrDest, 0, arrDest.Length, arrSource, 0, arrSource.Length, num, bitmovSource, bitmov);
		}
		/// <summary>
		/// 将arrSource数组指定部分护具按指定位偏移，与按指定位偏移的num叠加，然后将结果保存到arrDest数组中的指定位置去。位偏移量都是相对结果数组arrDest而言，超出范围的数据将被舍去。
		/// </summary>
		/// <param name="arrDest">存放结果的数组</param>
		/// <param name="indexDest">结果数组存放起始索引（从0开始）</param>
		/// <param name="lenDest">结果数组存放数据长度</param>
		/// <param name="arrSource">被加数数组</param>
		/// <param name="indexSource">被加数数组起始索引（从0开始）</param>
		/// <param name="lenSource">被加数数据长度</param>
		/// <param name="arrOther">加数数组</param>
		/// <param name="indexOther">加数数组起始索引（从0开始）</param>
		/// <param name="lenOther">加数数据长度</param>
		/// <param name="bitmovSource">被加数相对结果数组指定部分最低位的位偏移</param>
		/// <param name="bitmovOther">加数相对结果数组指定部分最低位的位偏移</param>
		/// <returns>进位（超出结果数组数据范围）</returns>
		public static bool Plus(ulong[] arrDest, int indexDest,int lenDest, ulong[] arrSource, int indexSource, int lenSource, ulong[] arrOther, int indexOther, int lenOther, int bitmovSource, int bitmovOther)
		{
			bitmovSource = -bitmovSource;
			bitmovOther = -bitmovOther;
			bool flag = false;
			for (int i = 0; i < lenDest; ++i)
			{
				ulong tmp1 = GetULong(arrSource,indexSource, lenSource, bitmovSource);
				ulong tmp2 = GetULong(arrOther,indexOther, lenOther, bitmovOther);
				if (flag)
				{
					flag = tmp1 >= ~tmp2;
					arrDest[indexDest+i] = tmp1 + tmp2 + 1;
				}
				else
				{
					flag = tmp1 > ~tmp2;
					arrDest[indexDest+i] = tmp1 + tmp2;
				}
				bitmovSource += 64;
				bitmovOther += 64;
			}
			return flag;
		}
		public static bool Plus(ulong[] arrDest,ulong[] arrSource, ulong[] arrOther, int bitmovSource=0, int bitmovOther=0) {
			return Plus(arrDest, 0, arrDest.Length, arrSource, 0, arrSource.Length, arrOther, 0, arrOther.Length, bitmovSource, bitmovOther);
		}
		/// <summary>
		/// 将arrSource数组指定部分护具按指定位偏移，与按指定位偏移的num叠加，然后将结果保存到arrDest数组中的指定位置去。位偏移量都是相对结果数组arrDest而言，超出上限的数据将被舍去，超下限的数据视情况舍入。
		/// </summary>
		/// <param name="arrDest">存放结果的数组</param>
		/// <param name="indexDest">结果数组存放起始索引（从0开始）</param>
		/// <param name="lenDest">结果数组存放数据长度</param>
		/// <param name="arrSource">被加数数组</param>
		/// <param name="indexSource">被加数数组起始索引（从0开始）</param>
		/// <param name="lenSource">被加数数据长度</param>
		/// <param name="arrOther">加数数组</param>
		/// <param name="indexOther">加数数组起始索引（从0开始）</param>
		/// <param name="lenOther">加数数据长度</param>
		/// <param name="bitmovSource">被加数相对结果数组指定部分最低位的位偏移</param>
		/// <param name="bitmovOther">加数相对结果数组指定部分最低位的位偏移</param>
		/// <returns>进位（超出结果数组数据范围，舍入导致进位有大于1的可能）</returns>
		public static int PlusRound(ulong[] arrDest, int indexDest, int lenDest, ulong[] arrSource, int indexSource, int lenSource, ulong[] arrOther, int indexOther, int lenOther, int bitmovSource, int bitmovOther)
		{
			bitmovSource = -bitmovSource;
			bitmovOther = -bitmovOther;
			ulong tmp1 = GetULong(arrSource, indexSource,lenSource, bitmovSource - 64);
			ulong tmp2 = GetULong(arrOther, indexOther,lenOther, bitmovOther - 64);
			int flag = (tmp1 > ~tmp2?1:0) + ((long)(tmp1 + tmp2) < 0?1:0);

			for (int i = 0; i < lenDest; ++i)
			{
				tmp1 = GetULong(arrSource, indexSource,lenSource, bitmovSource);
				tmp2 = GetULong(arrOther, indexOther,lenOther, bitmovOther);
				if (flag != 0)
				{
					if (flag == 2)
					{
						flag = (tmp1 ==  ~0ul) && (tmp2 == ~0ul)? 2 :
							tmp1 != ~0ul ?( tmp1 +1 >= ~tmp2)?1:0 : 1;
						arrDest[indexDest+i] = tmp1 + tmp2 + 2;
					}
					else
					{
						flag = tmp1 >= ~tmp2?1:0;
						arrDest[indexDest+i] = tmp1 + tmp2 + 1;
					}
				}
				else
				{
					flag = tmp1 > ~tmp2?1:0;
					arrDest[indexDest+i] = tmp1 + tmp2;
				}
				bitmovSource += 64;
				bitmovOther += 64;
			}
			return flag;
		}
		public static int PlusRound(ulong[] arrDest, ulong[] arrSource, ulong[] arrOther, int bitmovSource = 0, int bitmovOther = 0)
		{
			return PlusRound(arrDest, 0, arrDest.Length, arrSource, 0, arrSource.Length, arrOther, 0, arrOther.Length, bitmovSource, bitmovOther);
		}
	}
}
